<script lang="ts" setup>
import { ref } from "vue";
import {toast} from "../../components/popup/popup";
import UniIcons from "../../uni_modules/uni-icons/components/uni-icons/uni-icons.vue";
import {baseUrl} from "../../api/http";
import BHeader from "../../components/header/bHeader.vue";
import UniDrawer from "../../uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue";
import {getChatPageList,addChatPage,delChatPage,putChatPage} from "../../api/chat/charPage"
import {getChatHistoryList} from "../../api/chat/chatHistory"
import {getUserId} from "../../store"
import UniSwipeAction from "../../uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue";
import UniSwipeActionItem from "../../uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue";
import UniPopupDialog from "../../uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue";
import UniPopup from "../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue";
import {getEvent} from "../../composables/useAI";
import {testChat} from "../../api/chat/chat"
import UniSection from "../../uni_modules/uni-section/components/uni-section/uni-section.vue";
import {addAnnouncement,publicAnnouncement} from "../../api/announcement"


const inputContent = ref("");
const isThinking = ref(false);
const scrollTop = ref(0);
const diaBox = ref()
const diaAnn = ref()
const curPage = ref(0)
const history:any = ref([])

const AnnFromData = ref({
  id: 0,
  annTitle: "",
  annContent: "",
  annContect: "",
  updateBy: getUserId(),
})


//抽屉
let drawer = ref()

const messages = ref([
  {
    type: "ai",
    thinkContent: "",
    content: "你好！我是你的智能助手，有什么我可以帮你的吗？",
    time: new Date().toLocaleTimeString("zh-CN", { hour12: false }).slice(0, 5),
    think: false,
    event: "已完成"
  },
]);

const handleInput = () => {
  // 输入框自适应
};

const handleSend = () => {


  if (!inputContent.value.trim()) return;
  isThinking.value = true;
  // 添加用户消息
  messages.value.push({
    type: "user",
    thinkContent: "",
    content: inputContent.value,
    time: new Date().toLocaleTimeString("zh-CN", { hour12: false }).slice(0, 5),
    think: false,
    event: "已完成"
  });

  goBottom()
  let ai = new EventSource(baseUrl + "/chat?content=" + inputContent.value + "&pageId=" + curPage.value + "&userId=" + getUserId())

  let msg = {
    type: "ai",
    content: "",
    thinkContent: "",
    time: new Date().toLocaleTimeString("zh-CN", { hour12: false }).slice(0, 5),
    think: true,
    event: "加载模型中"
  }

  messages.value.push(msg)
  ai.onmessage = (event) => {
    isThinking.value = true;
    let text = JSON.parse(event.data)

    switch (getEvent(text['event'])) {
      case 0:
        messages.value[messages.value.length - 1].event = "输出中"
        if (text["isThink"] === 1  || text["content"] === "<think>" || text["content"] === "</think>") {
          messages.value[messages.value.length - 1].thinkContent += text["content"]
        } else {
          messages.value[messages.value.length - 1].content += text["content"]
        }

        if (text["data"] === "Ann") {

          if (text["type"] === "title") {
            AnnFromData.value.annTitle += text["content"]
          }

          if (text["type"] === "annContent") {
            AnnFromData.value.annContent += text["content"]
          }

          diaAnn.value.open()

        }


        break;

      case 1:
          messages.value[messages.value.length - 1].event = text["content"]
          messages.value[messages.value.length - 1].content += "\n"
        break;
      case 2:
        break;
    }
    goBottom()

    if (text["event"] === "end") {
      ai.close()
      messages.value[messages.value.length - 1].event = "已完成"
      messages.value[messages.value.length - 1].think = false;
      isThinking.value = false;
    }


  }

  ai.onerror = (event) => {
    messages.value[messages.value.length - 1].event = "已完成"
    messages.value[messages.value.length - 1].think = false;
    isThinking.value = false;
    ai.close()
  }

  // 清空输入
  inputContent.value = "";

};


const handleMessageLongPress = (message: any) => {
  //@ts-ignore
  uni.showActionSheet({
    itemList: ["复制", "分享"],
    success: res => {
      if (res["tapIndex"] === 0) {
        //@ts-ignore
        uni.setClipboardData({
          data: message.content,
          success: () => {
            toast(`已复制AI回复`,"none")
          },
        });
      } else if (res["tapIndex"] === 1) {
        toast("分享功能开发中", "none")
      }
    },
  });
};

const loadMoreHistory = () => {
    toast("加载历史对话记录中", "none")
};

//折叠思考内容
const handleThink = (msg) => {
  msg.think = !msg.think
};

const putChatPageName = (val) => {

  putChatPage({
    id: curPage.value + "",
    pageName: val + "",
    updateBy: getUserId() + ""
  }).then(res => {
    toast("修改成功", "none")
    history.value.forEach((item) => {
      if (item["id"] == curPage.value) {
        item["pageName"] = val
      }
    })
  })

}

const openDrawer = () => {
  drawer.value.open()
}

const geyHistory = async () => {
  await new Promise(resolve => {
    getChatPageList(getUserId() + "").then(res => {
      history.value = res.data

      if (history.value.length == 0) {
        //新增策略
        addChatPage({
          userId: getUserId(),
          updateBy: getUserId()
        }).then(res => {
          curPage.value = res.data

          getChatHistoryList(curPage.value).then( res => {
            messages.value.push(...res.data)

            goBottom()
            resolve()
          })

        })

      } else {
        curPage.value = history.value[0]["id"]
        getChatHistoryList(curPage.value).then( res => {
          messages.value.push(...res.data)

          goBottom()

          resolve()

        })
      }
    })
  })
}

const options = ref([
  {
    text: "修改",
    style: {
      backgroundColor: "#007aff",
    }
  },{
     text: "删除",
     style: {
       backgroundColor: "red",
    }
}])

const handOptionClick = (e) => {
  if (e.content.text === "删除") {
    delChatPage(curPage.value).then(res => {
      history.value = history.value.filter(
          (item) => item.id !== curPage.value
      )
    })
  } else {
    drawer.value.close()
    diaBox.value.open()
  }
}

const handOptionChange = (e) => {
  curPage.value = e.id
  drawer.value.close()
  messages.value = []
  getChatHistoryList(curPage.value).then( res => {
    messages.value.push(...res.data)
  })
}

const handAddPage = () => {
  addChatPage({
    userId: getUserId(),
    updateBy: getUserId()
  }).then(res => {
    curPage.value = res.data
    history.value.push({
      id: res.data,
      pageName: "new Page",
      time: new Date().toLocaleTimeString("zh-CN", { hour12: false }).slice(0, 5)
    })

  })
}

//新增公告
const handAddAnn = () => {
  addAnnouncement(AnnFromData.value).then(res => {
    if (res["code"] === 200) {
      toast("发布成功", "none")
      AnnFromData.value.id = res.data.id
      publicAnnouncement(AnnFromData.value).then(res => {
        AnnFromData.value = {
          id: 0,
          updateBy: getUserId(),
          annTitle: "",
          annContent: "",
          annContect: ""
        }
      })
      diaAnn.value.close()
    }
  })
}

const qx = () => {
  AnnFromData.value = {
    id: 0,
    updateBy: getUserId(),
    annTitle: "",
    annContent: "",
    annContect: ""
  }
  diaAnn.value.close()
}

const init = () => {
  geyHistory()
}

const goBottom = () => {
  let a = document.getElementById("msg")
  let n = document.getElementById("con")
  a.scrollIntoView(false)
  n.scrollIntoView(false)
}

init()

let userMedia: Promise<MediaStream>;
let media: MediaRecorder;
let isRecording = ref(false);
let chunks = []

const handMediaStreamStart = () => {
  toast("语音开始", "none")
  userMedia = navigator.mediaDevices.getUserMedia({
    audio: true,
  });

  userMedia.then(stream => {
    media = new MediaRecorder(stream);
    media.start()

    media.ondataavailable = (e) => {
      chunks.push(e.data)
    }

    isRecording.value = true
  })

};

const handMediaStreamStop = () => {
  toast("语音结束", "none")

  isRecording.value = false;
  media.stop()
  media.onstop = () => {

    isRecording.value = false

    let blob = new Blob(chunks, {type: "audio/wav"})

    let a = window.URL.createObjectURL(blob)

    let audio = new Audio(a);
    audio.play()
    chunks = []
    media = null
    userMedia = null

    let c = new FormData()
    c.append("re", blob)
    testChat(c).then(res => {
    })
  }

}

</script>

<template>

  <uni-popup ref="diaAnn" class="box">
    <view class="box_a">
      <uni-section title="公告标题" type="line">
        <input v-model="AnnFromData.annTitle" placeholder="公告标题" />
      </uni-section>

      <uni-section title="公告内容" type="line">
        <textarea v-model="AnnFromData.annContent" placeholder="公告内容" />
      </uni-section>

      <uni-section title="联系方式" type="line">
        <input type="number" v-model="AnnFromData.annContect" placeholder="联系方式" />
      </uni-section>

      <uni-section title="" >
        <button size="mini" type="primary" @click="handAddAnn">发布</button>
        <button size="mini"  @click="qx">取消</button>
      </uni-section>

    </view>
  </uni-popup>


  <uni-popup ref="diaBox">
    <uni-popup-dialog
        title="修改名称"
        mode="input"
        placeholder="请输入内容"
        @confirm="putChatPageName"
    />
  </uni-popup>

  <view class="back">
    <view class="header_fixed">
      <b-header title="ai助手">
        <view class="header-right">
          <button size="mini" type="primary" @click="openDrawer">历史任务</button>
        </view>
      </b-header>
    </view>

    <uni-drawer ref="drawer" mode="right">
        <view class="history_list">
          <text>历史对话记录</text>
        </view>
        <view class="list">
            <view class="item" @click="handAddPage">
              <text class="name">新增任务 +</text>
              <text class="time">时间：{{new Date().toLocaleTimeString("zh-CN", { hour12: false }).slice(0, 5)}}</text>
            </view>
            <uni-swipe-action v-for="(i, index) in history" :key="index">
              <uni-swipe-action-item
                  :right-options="options"
                  @change="handOptionChange(i)"
                  @click="handOptionClick"
              >
                <view class="item" @click="handOptionChange(i)">
                  <text class="name">{{i["pageName"]}}</text>
                  <text class="time">时间：{{i["time"]}}</text>
                </view>
              </uni-swipe-action-item>
            </uni-swipe-action>
        </view>
    </uni-drawer>

    <view class="container" id="con">
      <!-- 对话内容区 -->
      <scroll-view
          id="msg"
          class="chat-content"
          scroll-y
          :scroll-top="scrollTop"
          @scrolltoupper="loadMoreHistory"
          ref="chatScrollView"
      >
        <view class="message-list">
          <view
              v-for="(message, index) in messages"
              :key="index"
              :class="['message-item', message.type === 'user' ? 'message-right' : 'message-left']"
          >
            <view
                class="message-bubble"
                @longpress="handleMessageLongPress(message)"
            >
              <view class="message-text">

                <view class="think_head" v-if="message.type === 'ai' && message.thinkContent.length !== 0">
                  <text>思考内容</text>
                  <text @click="handleThink(message)" style="color: #aaaaaa"> {{message["think"] ? '收起':'展开'}}</text>
                </view>
                <text class="think" v-if="message['think']" >{{ message.thinkContent }}</text>

                <text class="message_info">{{ message.content }}</text>

                <view class="eventStatus">
                  <text>{{message.event}}</text>
                  <view v-if="message.think && isThinking" class="thinking">
                    <view class="dot-loading">
                      <view class="dot"></view>
                      <view class="dot"></view>
                      <view class="dot"></view>
                    </view>
                  </view>
                </view>
              </view>
            </view>
            <view class="message-time">{{ message.time }}</view>
          </view>
        </view>
      </scroll-view>

      <!-- 底部输入区 -->
      <view class="input-area">
        <view class="input-container">
        <textarea
            class="input-box"
            v-model="inputContent"
            :maxlength="-1"
            :adjust-position="false"
            :show-confirm-bar="false"
            :cursor-spacing="20"
            :autoheight="true"
            placeholder="请输入消息..."
            @input="handleInput"
        ></textarea>
          <view class="button-group">
            <uni-icons
                type="mic-filled"
                size="24"
                color="#666"
                @touchstart="handMediaStreamStart"
                @touchend="handMediaStreamStop"
                class="voice-btn"
            ></uni-icons>
            <button
                class="send-btn"
                :disabled="!inputContent.trim()"
                @click="handleSend"
            >
              <uni-icons
                  :type="isThinking ? 'closeempty' : 'paperplane'"
                  size="20"
                  color="#fff"
              ></uni-icons>
            </button>
          </view>
        </view>
      </view>
    </view>

  </view>
</template>



<style scoped lang="scss">

@use "../../static/css/main";

.box {

  @include main.useTheme() {
    .box_a{
      button{
        margin-left: 10px;
      }

      .uni-section{
        background-color: main.getVal("primary_bg_color");
      }
      input {
        border-bottom: 1px solid main.getVal("one_lv_border_color");
        width: 90%;
        margin-left: 10px;
      }
      textarea {
        border-bottom: 1px solid main.getVal("one_lv_border_color");
        width: 90%;
        margin-left: 10px;
      }
      min-width: 80vw;
      border-radius: 10rpx;
      padding: 20rpx 20rpx 30rpx;
      background-color: main.getVal("primary_bg_color");

    }
  }
}

.back {
  @include main.useTheme() {
    .message-list{
      scroll-behavior: smooth;
    }
    .header_fixed{
      position: fixed;
      width: 100%;
      z-index: 10;
    }
    .list {
      .item:active {
        background-color: main.getVal("two_lv_bg_color");
      }

      .item {
        .name {
          font-size: 4vw;
        }
        .time {
          font-size: 2.6vw;
          color: main.getVal("other_lv_text_color");
        }
        display: flex;
        flex-direction: column;
        padding: 20rpx;
        border-bottom: 1px solid main.getVal("one_lv_border_color");
      }
      display: flex;
      flex-direction: column;
    }
    .history_list{
      padding: 30rpx;
    }
    .header-right{
      display: flex;
      align-items: center;
    }

    .think_head{
      display: flex;
      justify-content: end;
      margin: 10rpx 0;
    }

    .btn {
      color: #7e7e7e;
    }

    .think {
      background-color: main.getVal("two_lv_bg_color");
      display: block;
      padding: 5px 20rpx;
      border-radius: 10rpx;
    }

    .container {
      display: flex;
      flex-direction: column;
      height: 100vh;
      padding-top: 50rpx;
      background-color: main.getVal("two_lv_bg_color");
    }

    .chat-content {
      flex: 1;
      overflow: auto;
      transform: translateY(50rpx);
      padding: 20rpx 20rpx 280rpx;
    }

    .message-item {
      .eventStatus {
        display: flex;
        align-items: center;
        color: main.getVal("two_lv_text_color");
        font-size: 20rpx;
        margin-top: 10rpx;
      }
      margin-bottom: 30rpx;
      display: flex;
      flex-direction: column;

    }


    .message-left {
      align-items: flex-start;
    }

    .message-right {
      align-items: flex-end;
    }

    .message-bubble {
      max-width: 70%;
      padding: 20rpx 30rpx;
      border-radius: 20rpx;
      word-break: break-all;
    }

    .message-left .message-bubble {
      background-color: main.getVal("primary_bg_color");
      border: 1px solid main.getVal("primary_border_color");
    }

    .message-right .message-bubble {
      background-color: #3498db;
    }

    .message-text {
      font-size: 14px;
      line-height: 1.5;
    }

    .message-right .message-text {
      color: #fff;
    }

    .message-left .message-text {
      color: main.getVal("one_lv_text_color");
    }

    .message-time {
      font-size: 12px;
      color: #999;
      margin-top: 10rpx;
    }

    .thinking {
      padding: 20rpx;
    }

    .dot-loading {
      display: flex;
      align-items: center;
      gap: 8rpx;
    }

    .dot {
      width: 12rpx;
      height: 12rpx;
      background-color: #999;
      border-radius: 50%;
      animation: dot-animation 1.4s infinite ease-in-out;
    }

    .dot:nth-child(2) {
      animation-delay: 0.2s;
    }

    .dot:nth-child(3) {
      animation-delay: 0.4s;
    }

    @keyframes dot-animation {
      0%,
      80%,
      100% {
        transform: scale(0);
      }
      40% {
        transform: scale(1);
      }
    }

    .input-area {
      position: fixed;
      bottom: 0;
      width: 100%;
      padding: 20rpx;
      background-color: main.getVal("primary_bg_color");
      border-top: 1px solid main.getVal("primary_border_color");
      flex-shrink: 0;
      z-index: 1;
    }

    .input-container {
      display: flex;
      align-items: flex-end;
      gap: 20rpx;
    }

    .input-box {
      flex: 1;
      min-height: 80rpx;
      max-height: 200rpx;
      padding: 20rpx;
      font-size: 14px;
      line-height: 1.5;
      background-color: main.getVal("one_lv_bg_color");
      border-radius: 20rpx;
    }

    .button-group {
      display: flex;
      align-items: center;
      gap: 20rpx;
    }

    .voice-btn {
      width: 48rpx;
      height: 48rpx;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .send-btn {
      width: 80rpx;
      height: 80rpx;
      padding: 0;
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #3498db;
      border-radius: 40rpx;
    }

    .send-btn:active {
      opacity: 0.8;
    }

    .send-btn[disabled] {
      background-color: #ccc;
    }
  }
}




</style>
